// $codepro.audit.disable multiplicationOrDivisionByPowersOf2, numericLiterals, logExceptions, com.instantiations.assist.eclipse.analysis.unusedReturnValue
/**
 * This file was created by Nick Popescu for use in SpaceTrader
 */
import javax.swing.JPanel;
//import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JOptionPane;

/**
 * This is the visual representation of a Marketplace which provides the GUI
 * representations and componenets for buying and selling items.
 * 
 * @author Nick Popescu
 * @version 1.0
 */

public class MarketplaceScreen extends JPanel implements MouseMotionListener,
	MouseListener {

    /**
     * Checks if we're in buy mode
     */
    private boolean buyMode = true;

    /**
     * The bounds of the buy icons
     */
    private Rectangle[] buyIconBoundsArray;

    /**
     * The bounds of the sell icons
     */
    private Rectangle[] sellIconBoundsArray;

    /**
     * The bounds of the entire buy and sell area
     */
    private Rectangle[] buySellBoundsArray;

    /**
     * The resource you're hovering over
     */
    private Resource hoveringResource = null;

    /**
     * This represents the spacing resolution information
     */
    private static final int SPACINGRESINFO = 10;

    /**
     * This rperesents the size of the Text
     */
    private static final int TEXTSIZE = 14;

    /**
     * The marketplace where the player is currently at
     */
    private Marketplace currMarketplace = Game.Player.getCurrentPlanet()
	    .getMarketplace();

    /**
     * This is a dummy variable, should not be used in any nessicary methods
     */
    private int dummy = 0;

    /**
     * An array of images used to represent items
     */
    private final Image[] resourceImageArray = {
	    Toolkit.getDefaultToolkit().getImage("imgs//water.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//furs.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//food.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//ore.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//games.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//firearms.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//medicine.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//machines.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//narcotics.png"),
	    Toolkit.getDefaultToolkit().getImage("imgs//robots.png") };

    /**
     * Creates a Marketplace Screen, which is a GUI for the marketplace.
     */

    public MarketplaceScreen() { // $codepro.audit.disable
				 // com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.constructorsOnlyInvokeFinalMethods
	setOpaque(false);
	addMouseListener(this);
	addMouseMotionListener(this);
	setLayout(null);
    }

    /**
     * This is what draws everything on the Marketplace panel. It draws all the
     * items, and GUI components.
     * 
     * @param g
     *            The required Graphics component that everything is drawn on.
     */
    @Override
    public void paintComponent(Graphics g) {
	super.paintComponent(g); // paints all the parent stuff.

	final Graphics2D g2d = (Graphics2D) g; // makes a new Graphics2D, which
					       // provides drawing tools.

	// Dimension size = getSize(); // Size of the Space grid.

	// Stores the resources for display.
	final Resource[] resources = Game.Player.getCurrentPlanet()
		.getMarketplace().getResources();
	final Resource[] cargo = Game.Player.getShip().getCargo();
	currMarketplace = Game.Player.getCurrentPlanet().getMarketplace();

	/**
	 * for(int i = 0; i < resources.length; i++){
	 * System.out.print(resources[i].getName()+" "); }
	 */
	final int sellBuyHeight = 20;
	final int resInfoWidth = this.getWidth() / 2;
	final int resInfoHeight = this.getHeight() / 2 - SPACINGRESINFO / 2;

	g2d.setColor(Color.WHITE);
	g2d.drawRect(resInfoWidth / 2, SPACINGRESINFO / 2, resInfoWidth, // $codepro.audit.disable
									 // expressionValue
		resInfoHeight);

	// int TEXTSIZE = 14;

	// Checks if the mouse is pointing to a resource, and displays
	// more information about that item.
	if (hoveringResource != null) {
	    final Font font = new Font(Font.SANS_SERIF, Font.BOLD, TEXTSIZE);// Sets
									     // the
									     // font
									     // of
									     // the
									     // text.
	    g.setFont(font);
	    g.setColor(Color.green);

	    g2d.drawString(hoveringResource.getName(), resInfoWidth / 2
		    + SPACINGRESINFO, 2 * SPACINGRESINFO); // $codepro.audit.disable
							   // expressionValue

	    final Font font2 = new Font(Font.SANS_SERIF, Font.BOLD,
		    TEXTSIZE - 2);// Sets
				  // the
				  // font
				  // of
				  // the
				  // text.
	    g.setFont(font2);
	    g.setColor(Color.orange);
	    g2d.drawString(
		    "Availability: " + hoveringResource.getMultiplicity(),
		    resInfoWidth / 2 + SPACINGRESINFO, TEXTSIZE + 2 // $codepro.audit.disable
								    // expressionValue
			    * SPACINGRESINFO);// $codepro.audit.disable
					      // expressionValue

	    final Font font3 = new Font(Font.SANS_SERIF, Font.BOLD,
		    TEXTSIZE - 2);// Sets
				  // the
				  // font
				  // of
				  // the
				  // text.
	    g.setFont(font3);
	    g.setColor(Color.orange);

	    for (int i = 0; i < resources.length; i++) {
		if (resources[i].getIndex() == hoveringResource.getIndex()) {
		    g2d.drawString("Price: " + resources[i].getPrice(),
			    resInfoWidth / 2 + SPACINGRESINFO, 2 * TEXTSIZE + 2 // $codepro.audit.disable
										// expressionValue
				    * SPACINGRESINFO);
		}
	    }

	}

	g.setColor(Color.white);

	// These draw the rectangles for the Buy/Sell GUY areas.
	final int[] buyAreaPolyX = new int[] { SPACINGRESINFO,
		resInfoWidth / 2 - SPACINGRESINFO,
		resInfoWidth / 2 - SPACINGRESINFO,
		this.getWidth() - SPACINGRESINFO,
		this.getWidth() - SPACINGRESINFO, SPACINGRESINFO };

	final int[] buyAreaPolyY = new int[] {
		SPACINGRESINFO + resInfoHeight - sellBuyHeight,
		SPACINGRESINFO + resInfoHeight - sellBuyHeight,
		this.getHeight() / 2 + SPACINGRESINFO,
		this.getHeight() / 2 + SPACINGRESINFO,
		this.getHeight() - SPACINGRESINFO,
		this.getHeight() - SPACINGRESINFO };

	final int[] sellAreaPolyX = new int[] { SPACINGRESINFO,
		this.getWidth() - (resInfoWidth / 2 - SPACINGRESINFO),
		this.getWidth() - (resInfoWidth / 2 - SPACINGRESINFO),
		this.getWidth() - SPACINGRESINFO,
		this.getWidth() - SPACINGRESINFO, SPACINGRESINFO };

	final int[] sellAreaPolyY = new int[] {
		this.getHeight() / 2 + SPACINGRESINFO,
		this.getHeight() / 2 + SPACINGRESINFO,
		SPACINGRESINFO + resInfoHeight - sellBuyHeight,
		SPACINGRESINFO + resInfoHeight - sellBuyHeight,
		this.getHeight() - SPACINGRESINFO,
		this.getHeight() - SPACINGRESINFO };

	// g2d.drawPolygon(sellAreaPolyX, sellAreaPolyY, sellAreaPolyX.length);
	if (buyMode) {
	    g2d.drawPolygon(buyAreaPolyX, buyAreaPolyY, buyAreaPolyX.length);
	} else {
	    g2d.drawPolygon(sellAreaPolyX, sellAreaPolyY, sellAreaPolyX.length);
	}

	// Draw the buttons to switch between Buying/Selling.
	final Image buyBtnImage = Toolkit.getDefaultToolkit().getImage(
		"imgs//buyBtn.png");
	final Image sellBtnImage = Toolkit.getDefaultToolkit().getImage(
		"imgs//sellBtn.png");

	g.drawImage(buyBtnImage, SPACINGRESINFO + SPACINGRESINFO / 2, // $codepro.audit.disable
								      // expressionValue
		SPACINGRESINFO + resInfoHeight - sellBuyHeight, this);
	g.drawImage(sellBtnImage, this.getWidth() - SPACINGRESINFO
		- sellBtnImage.getWidth(this), SPACINGRESINFO + resInfoHeight
		- sellBuyHeight, this);

	buySellBoundsArray = new Rectangle[2];

	buySellBoundsArray[0] = new Rectangle(SPACINGRESINFO + SPACINGRESINFO // $codepro.audit.disable
									      // expressionValue
		/ 2, SPACINGRESINFO + resInfoHeight - sellBuyHeight, // $codepro.audit.disable
								     // expressionValue
		buyBtnImage.getWidth(this), buyBtnImage.getHeight(this));
	buySellBoundsArray[1] = new Rectangle(this.getWidth() - SPACINGRESINFO
		- sellBtnImage.getWidth(this), SPACINGRESINFO + resInfoHeight
		- sellBuyHeight, sellBtnImage.getWidth(this),
		sellBtnImage.getHeight(this));

	// Draws the Buyable items.

	if (buyMode) {

	    // final int itemBoxWidth = 30;
	    // final int itemBoxHeight = 30;
	    final int itemBoxYStart = this.getHeight() / 2 - SPACINGRESINFO;
	    // final int boxesPerRow = 5;

	    // g.drawImage(resources[0].getImage(), 50, itemBoxYStart, this);
	    final int rows = 3;
	    final int cols = 6;
	    buyIconBoundsArray = new Rectangle[resources.length];

	    for (int y = 1; y < rows; y++) {
		for (int x = 1; x < cols; x++) {
		    if (((y - 1) * cols) + x <= resources.length) {
			g.drawImage(
				resourceImageArray[resources[(cols * (y - 1))
					+ (x - 1)].getIndex()],
				x * this.getWidth() / 7, itemBoxYStart
					+ (y * 30), this);
			buyIconBoundsArray[(cols * (y - 1)) + (x - 1)] = new Rectangle(
				x * this.getWidth() / 7, itemBoxYStart
					+ (y * 30),
				resourceImageArray[resources[(cols * (y - 1))
					+ (x - 1)].getIndex()].getWidth(this),
				resourceImageArray[resources[(cols * (y - 1))
					+ (x - 1)].getIndex()].getHeight(this));

		    }
		}
		// g.drawImage(resources[i].getImage(), i*50, itemBoxYStart,
		// this);

	    }

	    // Draws the Sell Mode items

	} else {
	    // final int itemBoxWidth = 30;
	    // final int itemBoxHeight = 30;
	    final int itemBoxYStart = this.getHeight() / 2 - SPACINGRESINFO;
	    // final int boxesPerRow = 5;

	    // g.drawImage(resources[0].getImage(), 50, itemBoxYStart, this);
	    // int rows = 2;
	    final int cols = 5;

	    int numItemTypesOnShip = 0;
	    for (int i = 0; i < cargo.length; i++) {
		if (cargo[i].getMultiplicity() > 0) {
		    numItemTypesOnShip++;
		}
	    }
	    sellIconBoundsArray = new Rectangle[numItemTypesOnShip];

	    int cargoDrawn = 1;

	    for (int i = 0; i < cargo.length; i++) {

		if (cargo[i].getMultiplicity() > 0) {

		    g.drawImage(resourceImageArray[cargo[i].getIndex()],
			    cargoDrawn % cols * this.getWidth() / 7,
			    itemBoxYStart + (cargoDrawn / cols) * (30) + 30,
			    this);

		    sellIconBoundsArray[cargoDrawn - 1] = new Rectangle(
			    cargoDrawn % cols * this.getWidth() / 7,
			    itemBoxYStart + (cargoDrawn / cols) * (30) + 30,
			    resourceImageArray[cargo[i].getIndex()]
				    .getWidth(this),
			    resourceImageArray[cargo[i].getIndex()]
				    .getHeight(this));

		    cargoDrawn++;

		}

	    }

	    /*
	     * for(int i = 0; i < sellIconBoundsArray.length; i++){
	     * System.out.print(sellIconBoundsArray[i]+" ");
	     * 
	     * } System.out.println();
	     */

	}

	// Display player's money.

	final Font font = new Font(Font.SANS_SERIF, Font.BOLD, TEXTSIZE);// Sets
									 // the
									 // font
									 // of
									 // the
									 // text.
	g.setFont(font);
	g.setColor(Color.white);

	g2d.drawString("$" + Game.Player.getWallet(), resInfoWidth / 2
		+ resInfoWidth + SPACINGRESINFO, SPACINGRESINFO + resInfoHeight
		- sellBuyHeight - TEXTSIZE);

    }

    /**
     * This handles the mouse movement event.
     * 
     * @param e
     *            The Mouse Event that represents mouse movement.
     */

    @Override
    public void mouseMoved(MouseEvent e) {

	if (buyMode) {
	    final Resource[] resources = Game.Player.getCurrentPlanet()
		    .getMarketplace().getResources();
	    boolean flag = false;
	    for (int i = 0; i < buyIconBoundsArray.length; i++) {
		// Registers which Resource the mouse is currently hovering
		// over.
		if (buyIconBoundsArray[i] != null
			&& buyIconBoundsArray[i].contains(e.getPoint())) {
		    // System.out.println("You Clicked on "+resources[i].getName());
		    // System.out.println(Game.Player.getCurrentPlanet().getMarketplace().canBuy(i,0));
		    flag = true;
		    hoveringResource = resources[i];
		}

	    }

	    if (!flag) {
		hoveringResource = null;
	    }

	} else {// sell mode
	    final Resource[] cargo = Game.Player.getShip().getCargo();
	    // final Resource[] resources = Game.Player.getCurrentPlanet()
	    // .getMarketplace().getResources();
	    boolean flag = false;
	    int currRectangle = 0;

	    for (int i = 0; i < cargo.length; i++) {
		if (cargo[i].getMultiplicity() > 0) {
		    if (sellIconBoundsArray[currRectangle].contains(e
			    .getPoint())) {

			flag = true;
			hoveringResource = cargo[i];

		    }
		    currRectangle++;
		}
	    }

	    if (!flag) {
		hoveringResource = null;
	    }

	    /*
	     * for(int i = 0; i<sellIconBoundsArray.length; i++){
	     * if(sellIconBoundsArray[i].contains(e.getPoint())){ for(int x = i;
	     * x < cargo.length; x++){ if(cargo[x].getMultiplicity()>0){
	     * 
	     * flag = true; hoveringResource = cargo[x];
	     * //System.out.println(cargo[x].getName()); break;
	     * 
	     * } } } }
	     * 
	     * 
	     * if(flag == false){ hoveringResource = null; }
	     */

	}

	repaint();

    }

    /**
     * Required by MouseMotionListener, but currently unused.
     * 
     * @param e
     *            The mouse dragged event.
     */
    @Override
    public void mouseDragged(MouseEvent e) {
	// System.out.println("Dragged!");
	dummy = 1;
    }

    /**
     * Required by the MouseListener. Checks if the mouse is clicked. If it is
     * clicked while the mouse is hovering by a planet, whose state changes to
     * Clickable, then does stuff that deals with that planet. Currently, it
     * just prints out information.
     * 
     * @param e
     *            The Mouse Event action
     */
    @Override
    public void mouseClicked(MouseEvent e) {
	// repaint();
	/**
	 * if(buyMode ){ buyMode = false; }else{ buyMode = true; }
	 */
	final Resource[] resources = Game.Player.getCurrentPlanet()
		.getMarketplace().getResources();
	final Resource[] cargo = Game.Player.getShip().getCargo();

	if (buyMode) {// Prompts the user with a message box to enter the number
		      // of items to buy.
		      // Then, buys the number of items. Lets the user know if
		      // it's not possible.

	    for (int i = 0; i < buyIconBoundsArray.length; i++) {

		if (buyIconBoundsArray[i] != null
			&& buyIconBoundsArray[i].contains(e.getPoint())) {
		    System.out.println("You Clicked on "
			    + resources[i].getName());
		    int quantity = -1;
		    try {
			Math.abs(quantity = Integer.parseInt(JOptionPane
				.showInputDialog(null,
					"How much of the resource ["
						+ resources[i].getName()
						+ "] would you like to buy?",
					"Buy " + resources[i].getName(), 1)));
		    } catch (NumberFormatException nfe) {
			JOptionPane.showMessageDialog(null,
				"You must enter a valid integer!");
		    }

		    if (quantity > -1) {
			if (!Game.Player.getCurrentPlanet().getMarketplace()
				.canBuy(i, quantity)) {
			    JOptionPane.showMessageDialog(null,
				    "You can't buy this item!");
			} else {
			    Game.Player.getCurrentPlanet().getMarketplace()
				    .buy(i, quantity);
			    // hoveringResource = null;
			}
		    }
		    System.out.println(Game.Player.getWallet());

		}
	    }

	    // If SELL mode

	    // Prompts the user with a message box to enter the number of items
	    // to buy.
	    // Then, buys the number of items. Lets the user know if it's not
	    // possible.
	} else {

	    // boolean flag = false;
	    int currRectangle = 0;

	    for (int i = 0; i < cargo.length; i++) {
		if (cargo[i].getMultiplicity() > 0) {
		    if (sellIconBoundsArray[currRectangle].contains(e
			    .getPoint())) {

			System.out.println("You Clicked on "
				+ cargo[i].getName());
			int quantity = -1;
			try {
			    Math.abs(quantity = Integer.parseInt(JOptionPane
				    .showInputDialog(
					    null,
					    "How much of the resource ["
						    + cargo[i].getName()
						    + "] would you like to sell?",
					    "Sell " + cargo[i].getName(), 1)));
			} catch (NumberFormatException nfe) {
			    JOptionPane.showMessageDialog(null,
				    "You must enter a valid integer!");
			}

			if (quantity > -1) {
			    if (!Game.Player.getCurrentPlanet()
				    .getMarketplace().canSell(i, quantity)) {
				JOptionPane.showMessageDialog(null,
					"You can't sell this item!");
			    } else {

				/*
				 * if(quantity>=cargo[x].getMultiplicity()){ int
				 * index = i; while(sellIconBoundsArray[index])
				 * sellIconBoundsArray. }
				 */

				Game.Player.getCurrentPlanet().getMarketplace()
					.sell(i, quantity);

				if (!Game.Player.getCurrentPlanet()
					.getMarketplace().canSell(i, 1)) {
				    hoveringResource = null;
				}

			    }
			}
			System.out.println(Game.Player.getWallet());

			repaint();

		    }
		    currRectangle++;
		}
	    }

	}

	// Checks whether Buy or Sell buttons were pressed.

	if (buySellBoundsArray[0].contains(e.getPoint())) {
	    if (!buyMode) {
		buyMode = true;
	    }
	}

	if (buySellBoundsArray[1].contains(e.getPoint())) {
	    if (buyMode) {
		buyMode = false;
	    }
	}

	// System.out.print(e.getPoint());
	repaint();
	Game.InitConfigScreen.getFrame().getContentPane().repaint();
    }

    /**
     * Required by MouseListener, but unused here.
     * 
     * @param e
     *            The associated event that triggers this.
     */
    @Override
    public void mousePressed(MouseEvent e) {
	dummy = 4;
    }

    /**
     * Required by MouseListener, but unused here.
     * 
     * @param e
     *            The associated event that triggers this.
     */
    @Override
    public void mouseReleased(MouseEvent e) {
	dummy = 3;
    }

    /**
     * Required by MouseListener, but unused here.
     * 
     * @param e
     *            The associated event that triggers this.
     */
    @Override
    public void mouseEntered(MouseEvent e) {
	dummy = 1;
    }

    /**
     * Required by MouseListener, but unused here.
     * 
     * @param e
     *            The associated event that triggers this.
     */
    @Override
    public void mouseExited(MouseEvent e) {
	dummy = 2;
    }

}
